using System.Xml;
using AutoMapper;
using Crossborder.Common.EventBusHelper;
using Crossborder.Common.RedisModule;
using Crossborder.Common.Utility.HttpHelper;
using Crossborder.Core.Const;
using Crossborder.Core.Dto;
using Crossborder.Core.Repository;
using Crossborder.Domian.Products;
using Crossborder.IService;
using Microsoft.EntityFrameworkCore.Query;

namespace Crossborder.Service.Products
{
    public partial class ProductService : IProductService
    {
        public IRepository<Categorys> _CatRep { get; set; }

        public IRepository<ProductInfos> _InfoRep { get; set; }

        public IRepository<ProductClassify> _ClassifyRep { get; set; }

        public IMapper _Map { get; set; }

        public IRedisWorker _RedisWorker { get; set; }

        private static object _Lock = new object();

        public ProductService(IRepository<Categorys> catRep,
        IRepository<ProductInfos> infoRep,
        IRepository<ProductClassify> classifyRep,
        IMapper map, IRedisWorker redisWorker,
        LocalEventBus<ShoppingCartInputDto> busShoppingCartInput)
        {
            _CatRep = catRep;
            _InfoRep = infoRep;
            _ClassifyRep = classifyRep;
            _RedisWorker = redisWorker;
            _Map = map;
            busShoppingCartInput.localEventHandler += ShoppingCartEventHandler;
        }

        public async Task<HttpResponsion> QueryProduct(ProductInputDto dto)
        {
            var data = await _InfoRep.GetAsync(o => o.ProductId == dto.ProductId);
            var result = _Map.Map<ProductDto>(data);
            result.Classify = await GetProductClassifiesByProductIdAsync(dto.ProductId);
            // result.Photos = 
            return HttpHelper.Success(result);
        }

        public async Task<HttpResponsion> QueryProductPage(int page, int size, ProductInputDto dto)
        {
            var sql = "select * from ProductInfos Where 1=1";
            var data = await _InfoRep.QueryPageAsync(page, size, sql, dto);
            var result = _Map.Map<List<ProductDto>>(data);
            return HttpHelper.Success(result);
        }

        public async Task<HttpResponsion> CreateProduct(ProductInputDto dto)
        {

            if (string.IsNullOrWhiteSpace(dto.CategoryId))
            {
                return HttpHelper.Fail("保存失败，没有选择类别！");
            }
            if (string.IsNullOrWhiteSpace(dto.SubCategoryId))
            {
                return HttpHelper.Fail("保存失败，没有选择二级类别！");
            }
            var product = _Map.Map<ProductInfos>(dto);
            product.Create();
            product.CategoryName = (await GetCategoryByCategoryId(dto.CategoryId)).CategoryName;
            product.SubCategoryName = (await GetCategoryByCategoryId(dto.SubCategoryId)).CategoryName;
            var result = await _InfoRep.InsertAsync(product);
            if (result == null)
            {
                return HttpHelper.Fail("创建失败！");
            }

            return HttpHelper.Success(result); ;
        }

        public async Task GetProductByProductNosInCacche(params string[] productNos)
        {
            foreach (var productNo in productNos)
            {
                var res = _RedisWorker.GetHashMemoryAsync<ProductDto>($"{RedisKeyName.PRODUCT_KEY}:{productNo}").Result;
                if (res == null)
                {
                    lock (_Lock)
                    {
                        res = _RedisWorker.GetHashMemoryAsync<ProductDto>($"{RedisKeyName.PRODUCT_KEY}:{productNo}").Result;
                        if (res == null)
                        {
                            res = _Map.Map<ProductDto>(GetProductByProductNos(productNo).Result.FirstOrDefault());
                            _RedisWorker.SetHashMemory($"{RedisKeyName.PRODUCT_KEY}:{productNo}", res);
                        }
                    }
                }
            }
        }

        private async Task<List<ProductDto>> GetProductByProductNos(params string[] productNos)
        {
            var data = await _InfoRep.GetListAsync(o => productNos.Contains(o.ProductNo));
            return _Map.Map<List<ProductDto>>(data);
        }

        private async Task<ProductDto> GetProductByProductId(string productId)
        {
            var product = await _InfoRep.GetAsync(o => o.ProductId == productId);
            var result = _Map.Map<ProductDto>(product);
            result.Classify = await GetProductClassifiesByProductIdAsync(productId);
            return result;
        }

        private async Task<ProductClassify> GetProductClassifyByClassifyId(string proClassifyId)
        {
            var classify = await _ClassifyRep.GetAsync(o => o.ProClassifyId == proClassifyId);
            return classify;
        }

        private async Task ShoppingCartEventHandler(ShoppingCartInputDto dto)
        {
            var product = await GetProductByProductId(dto.ProductId);
            var classify = await GetProductClassifyByClassifyId(dto.ProClassifyId);
            dto.ProductName = product?.ProductName ?? "";
            dto.CategoryName = product?.CategoryName ?? "";
            dto.SubCategoryName = product?.SubCategoryName ?? "";
            dto.Classify = classify;
        }
    }
}